package com.docmgmt.mvp.service;

import com.docmgmt.mvp.dto.KbSyncMessage;
import com.docmgmt.mvp.entity.*;
import com.docmgmt.mvp.mapper.*;
import com.docmgmt.mvp.ragflow.RAGFlowClient;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

/**
 * RAGFlow同步消费者（v3.0简化版）
 *
 * TODO: 当创建以下Mapper/Entity后恢复完整功能：
 * - KbSyncTaskMapper
 * - KbSyncLogMapper
 * - KbSyncTaskEntity
 * - KbSyncLogEntity
 *
 * 当前版本：仅处理文件同步，不记录任务状态和日志
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class KbSyncConsumer {

    private final RAGFlowClient ragflowClient;
    private final FileMapper fileMapper;
    private final KbFileMappingMapper kbFileMappingMapper;
    private final MinioClient minioClient;

    @Value("${minio.bucket-name:doc-storage}")
    private String bucketName;

    @RabbitListener(queues = "ragflow.sync.queue")
    @Transactional(rollbackFor = Exception.class)
    public void handleSync(KbSyncMessage message) {
        log.info("收到RAGFlow同步消息: {}", message);

        try {
            // 查询文件
            FileEntity file = fileMapper.selectById(message.getFileId());
            if (file == null) {
                log.error("文件不存在: fileId={}", message.getFileId());
                return;
            }

            if ("UPLOAD".equals(message.getAction())) {
                handleUploadSync(file);
            } else if ("DELETE".equals(message.getAction())) {
                handleDeleteSync(file);
            } else {
                log.warn("不支持的同步操作: {}", message.getAction());
            }

        } catch (Exception e) {
            log.error("RAGFlow同步失败: {}", message, e);
            // 简化版：不进行重试，直接抛出异常由RabbitMQ处理
            throw new RuntimeException("同步失败: " + e.getMessage(), e);
        }
    }

    /**
     * 处理上传同步
     */
    private void handleUploadSync(FileEntity file) throws Exception {
        log.info("开始上传文件到RAGFlow: fileId={}", file.getId());

        long startTime = System.currentTimeMillis();

        // 1. 从MinIO下载文件到临时文件
        File tempFile = File.createTempFile("ragflow-upload-", "-" + file.getFileName());
        try {
            try (InputStream stream = minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(file.getStoragePath())
                            .build())) {
                Files.copy(stream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            }

            // 2. 上传到RAGFlow（使用真实的RAGFlow dataset ID）
            String docId = ragflowClient.uploadDocument("64cb2314bbe011f08e7e6ab8e68c840f", tempFile);

            long duration = System.currentTimeMillis() - startTime;

            // 3. 触发文档自动解析（基于RAGFlow源码分析）
            // 根据源码研究，RAGFlow上传后不会自动解析，需要显式调用 /run 端点
            log.info("触发RAGFlow文档自动解析: fileId={}, docId={}", file.getId(), docId);
            try {
                ragflowClient.runDocument("64cb2314bbe011f08e7e6ab8e68c840f", docId);
                log.info("文档解析已触发，RAGFlow将在后台处理: docId={}", docId);
            } catch (Exception e) {
                log.warn("触发解析失败（不影响文档上传）: {}", e.getMessage());
            }

            // 4. 更新文件的ragflow_doc_id和同步状态
            file.setRagflowDocId(docId);
            file.setRagflowSyncStatus("synced");  // 更新状态为已同步
            fileMapper.updateById(file);

            // 5. 创建知识库文件映射（如果不存在）
            KbFileMappingEntity mapping = new KbFileMappingEntity();
            mapping.setKbId(1L);  // company_main_kb
            mapping.setFileId(file.getId());
            mapping.setFileStatus("active");
            mapping.setAddedBy(file.getUploadedBy());  // 设置添加人为文件上传者
            kbFileMappingMapper.insert(mapping);

            log.info("文件上传到RAGFlow成功: fileId={}, docId={}, 耗时{}ms", file.getId(), docId, duration);

        } finally {
            // 5. 删除临时文件
            if (tempFile.exists()) {
                tempFile.delete();
            }
        }
    }

    /**
     * 处理删除同步
     * TODO: 实现RAGFlowClient.deleteDocument方法后启用
     */
    private void handleDeleteSync(FileEntity file) throws Exception {
        log.info("开始从RAGFlow删除文件: fileId={}", file.getId());

        if (file.getRagflowDocId() != null) {
            log.warn("RAGFlow删除功能暂未实现: fileId={}, docId={}",
                    file.getId(), file.getRagflowDocId());
            // TODO: 当RAGFlowClient添加deleteDocument方法后启用以下代码
            /*
            long startTime = System.currentTimeMillis();
            ragflowClient.deleteDocument("company_main_kb", file.getRagflowDocId());
            long duration = System.currentTimeMillis() - startTime;

            log.info("文件从RAGFlow删除成功: fileId={}, docId={}, 耗时{}ms",
                    file.getId(), file.getRagflowDocId(), duration);
            */
        } else {
            log.warn("文件未同步到RAGFlow，无需删除: fileId={}", file.getId());
        }
    }
}
